package com.ruoyi.system.service.aggregation.impl;

import java.util.Date;
import java.util.List;
import java.util.UUID;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import com.ruoyi.common.utils.JwtTokenUtil;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.system.domain.aggregation.Account;
import com.ruoyi.system.domain.aggregation.User;
import com.ruoyi.system.mapper.aggregation.AccountMapper;
import com.ruoyi.system.mapper.aggregation.UserMapper;
import com.ruoyi.system.service.aggregation.IAggUserService;
import com.ruoyi.system.service.aggregation.ISalesmanNoService;
import com.ruoyi.system.service.aggregation.ISmsService;
import com.ruoyi.common.core.domain.aggregation.dto.LoginReqDTO;
import com.ruoyi.common.core.domain.aggregation.dto.UserRespDTO;
import java.util.concurrent.TimeUnit;

/**
 * 聚合码用户Service业务层处理
 * 
 * @author ruoyi
 * @date 2025-01-01
 */
@Service
public class AggUserServiceImpl implements IAggUserService 
{
    @Autowired
    private UserMapper userMapper;

    @Autowired
    private AccountMapper accountMapper;

    @Autowired
    private ISmsService smsService;

    @Autowired
    private ISalesmanNoService salesmanNoService;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    
    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    private BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
    
    private static final String TOKEN_PREFIX = "agg:token:";
    private static final int TOKEN_EXPIRE_TIME = 7 * 24 * 60; // 7天（分钟）

    /**
     * Web登录（账号密码登录）
     * 用于商家、业务员、区域代理、总公司后台登录
     */
    @Override
    public UserRespDTO login(LoginReqDTO loginReq)
    {
        if (!StringUtils.hasText(loginReq.getUserName()) || !StringUtils.hasText(loginReq.getPassWord()))
        {
            throw new ServiceException("手机号和密码不能为空");
        }

        // 查询用户
        User user = userMapper.selectUserByPhone(loginReq.getUserName());
        if (user == null)
        {
            throw new ServiceException("用户不存在");
        }

        // 验证密码
        if (!passwordEncoder.matches(loginReq.getPassWord(), user.getPassword()))
        {
            throw new ServiceException("密码错误");
        }

        // 验证用户类型（排除C端用户，类型1）
        if (user.getType() == 1)
        {
            throw new ServiceException("该登录方式不支持C端用户");
        }

        // 生成token并返回
        return generateUserResponse(user);
    }

    /**
     * App登录（手机验证码登录）
     * 用于小程序C端用户登录
     */
    @Override
    public UserRespDTO appLogin(LoginReqDTO loginReq)
    {
        if (!StringUtils.hasText(loginReq.getUserName()) || !StringUtils.hasText(loginReq.getCode()))
        {
            throw new ServiceException("手机号和验证码不能为空");
        }

        // 验证短信验证码
        if (!smsService.verifyCode(loginReq.getUserName(), loginReq.getCode()))
        {
            throw new ServiceException("验证码错误或已过期");
        }

        // 查询用户
        User user = userMapper.selectUserByPhone(loginReq.getUserName());
        
        // 如果用户不存在，自动注册C端用户
        if (user == null)
        {
            user = new User();
            user.setPhone(loginReq.getUserName());
            user.setName("用户" + loginReq.getUserName().substring(7)); // 简单的用户名
            user.setType(1); // C端用户
            user.setPassword(passwordEncoder.encode("123456")); // 默认密码
            user.setDeleted(0);
            user.setCreateTime(new Date());
            userMapper.insertUser(user);

            // 创建账户
            Account account = new Account();
            account.setUserId(user.getId());
            account.setBalance(0L);
            account.setTotalBalance(0L);
            account.setPeriod(DateUtils.dateTime(new Date()));
            account.setDeleted(0);
            account.setCreateTime(new Date());
            accountMapper.insertAccount(account);
        }

        // 生成token并返回
        return generateUserResponse(user);
    }

    /**
     * 忘记密码
     */
    @Override
    public void forgetPassword(LoginReqDTO loginReq)
    {
        if (!StringUtils.hasText(loginReq.getUserName()) || !StringUtils.hasText(loginReq.getCode())
                || !StringUtils.hasText(loginReq.getPassWord()))
        {
            throw new ServiceException("手机号、验证码和新密码不能为空");
        }

        // 验证短信验证码
        if (!smsService.verifyCode(loginReq.getUserName(), loginReq.getCode()))
        {
            throw new ServiceException("验证码错误或已过期");
        }

        // 查询用户
        User user = userMapper.selectUserByPhone(loginReq.getUserName());
        if (user == null)
        {
            throw new ServiceException("用户不存在");
        }

        // 更新密码
        user.setPassword(passwordEncoder.encode(loginReq.getPassWord()));
        user.setUpdateTime(new Date());
        userMapper.updateUser(user);
    }

    /**
     * 重置密码
     */
    @Override
    public void resetPassword(LoginReqDTO loginReq)
    {
        if (!StringUtils.hasText(loginReq.getUserName()) || !StringUtils.hasText(loginReq.getOldPassWord())
                || !StringUtils.hasText(loginReq.getPassWord()))
        {
            throw new ServiceException("手机号、旧密码和新密码不能为空");
        }

        // 查询用户
        User user = userMapper.selectUserByPhone(loginReq.getUserName());
        if (user == null)
        {
            throw new ServiceException("用户不存在");
        }

        // 验证旧密码
        if (!passwordEncoder.matches(loginReq.getOldPassWord(), user.getPassword()))
        {
            throw new ServiceException("旧密码错误");
        }

        // 更新密码
        user.setPassword(passwordEncoder.encode(loginReq.getPassWord()));
        user.setUpdateTime(new Date());
        userMapper.updateUser(user);
    }

    /**
     * 退出登录
     */
    @Override
    public void loginOut(String phone)
    {
        User user = userMapper.selectUserByPhone(phone);
        if (user != null)
        {
            String key = TOKEN_PREFIX + user.getId();
            redisTemplate.delete(key);
        }
    }

    /**
     * 生成用户响应数据和token
     */
    private UserRespDTO generateUserResponse(User user)
    {
        System.out.println("========== 生成用户JWT Token（混合模式） ==========");
        System.out.println("用户ID: " + user.getId());
        System.out.println("用户手机号: " + user.getPhone());
        
        // 1. 使用JwtTokenUtil生成JWT token（统一认证）
        // 用户名使用：agg_{userId} 格式，区分系统管理用户
        String username = "agg_" + user.getId();
        String token = jwtTokenUtil.generateToken(user.getId(), username);
        System.out.println("✅ 生成JWT Token: " + token.substring(0, Math.min(50, token.length())) + "...");
        
        // 2. 存储JWT token到Redis（用于单点登录、踢人下线）
        String redisKey = TOKEN_PREFIX + user.getId();
        try {
            // 存储token，实现单点登录（新登录会覆盖旧token）
            redisTemplate.opsForValue().set(redisKey, token, TOKEN_EXPIRE_TIME, TimeUnit.MINUTES);
            System.out.println("✅ Token已存储到Redis: " + redisKey);
            System.out.println("   有效期: " + TOKEN_EXPIRE_TIME + " 分钟 (7天)");
            
            // 验证存储
            Object storedToken = redisTemplate.opsForValue().get(redisKey);
            System.out.println("   验证存储: " + (token.equals(storedToken) ? "✅ 成功" : "❌ 失败"));
        } catch (Exception e) {
            System.out.println("❌ Redis存储失败: " + e.getMessage());
            // 即使Redis失败，JWT token仍然可以用（降级方案）
        }

        // 构建响应
        UserRespDTO response = new UserRespDTO();
        response.setId(user.getId());
        response.setName(user.getName());
        response.setPhone(user.getPhone());
        response.setType(user.getType());
        response.setToken(token);

        return response;
    }

    @Override
    public User selectUserById(Long id)
    {
        return userMapper.selectUserById(id);
    }

    @Override
    public User selectUserByPhone(String phone)
    {
        return userMapper.selectUserByPhone(phone);
    }

    @Override
    public List<User> selectUserList(User user)
    {
        return userMapper.selectUserList(user);
    }

    @Override
    public int insertUser(User user)
    {
        // 加密密码
        if (StringUtils.hasText(user.getPassword()))
        {
            user.setPassword(passwordEncoder.encode(user.getPassword()));
        }
        
        // 如果是业务员，自动生成8位编号
        if (user.getType() != null && user.getType() == 2) {
            if (!StringUtils.hasText(user.getSalesmanNo())) {
                String salesmanNo = salesmanNoService.generateNextSalesmanNo();
                user.setSalesmanNo(salesmanNo);
            }
        }
        
        user.setCreateTime(DateUtils.getNowDate());
        int result = userMapper.insertUser(user);

        // 创建账户
        if (result > 0)
        {
            Account account = new Account();
            account.setUserId(user.getId());
            account.setBalance(0L);
            account.setTotalBalance(0L);
            account.setPeriod(DateUtils.dateTime(new Date()));
            account.setDeleted(0);
            account.setCreateTime(new Date());
            accountMapper.insertAccount(account);
        }

        return result;
    }

    @Override
    public int updateUser(User user)
    {
        // 如果更新密码，需要加密
        if (StringUtils.hasText(user.getPassword()))
        {
            user.setPassword(passwordEncoder.encode(user.getPassword()));
        }
        user.setUpdateTime(DateUtils.getNowDate());
        return userMapper.updateUser(user);
    }

    @Override
    public int deleteUserById(Long id)
    {
        return userMapper.deleteUserById(id);
    }

    @Override
    public int deleteUserByIds(Long[] ids)
    {
        return userMapper.deleteUserByIds(ids);
    }
}

